//
//  AIStreamMessage.swift
//  NDAi
//
//  Created by 丸子 on 2024/6/27.
//

import UIKit
enum AIStreamMessageStatus {
    case `default`
    case finish
    case error
    case interrupt
}

struct AIStreamMessage {
    var event: String?
    var identify: String?
    var data: String = ""
    
    var status: AIStreamMessageStatus {
           switch event {
           case "add":
               return .default
           case "finish":
               return .finish
           case "error":
               return .error
           case "interrupted":
               return .interrupt
           default:
               return .default
           }
    }
 
    
    static func parseMessageFromResponse(response: String?) -> AIStreamMessage? {
        guard let response = response else { return nil }
        let eventArray = response.split(separator: "\n")
        var content = ""
        var isFinished = false
        for event in eventArray {
            if event.hasPrefix("data: ") {
                var eventData = String(event.dropFirst("data: ".count))
                if let data = eventData.data(using: .utf8),
                   let response = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                    
                    let p = AIParseMessagePart.deserialize(from: response)
                    let c = p?.choices.first
                    if let c = c, isEmpty(c.finish_reason) {
                        let text = c.delta?.content ?? ""
//                        let text = catString(c.delta?.content, catStringOrEmpty(c.deltas))
                        content.append(text)
                    }
                    isFinished = !isEmpty(c?.finish_reason)
                }
                print("Event Data: \(eventData)")
            }
        }
        var m = AIStreamMessage()
        m.event = isFinished ? "finish" : "add"
        m.identify = UUID().uuidString
        m.data = content
        return m
    }
    static func isEmpty(_ string: String?) -> Bool {
         guard let string = string else { return true }
         return string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
     }
    static func catString(_ string: String?, _ defaultString: String) -> String {
        guard let string = string else { return defaultString }
        return string
    }
    static func catStringOrEmpty(_ string: String?) -> String {
        return catString(string, "")
    }
    
    func merge(_ message: AIStreamMessage) -> AIStreamMessage {
         var mergedMessage = AIStreamMessage()
         mergedMessage.event = message.event
         mergedMessage.identify = message.identify
         mergedMessage.data = self.data + message.data
         return mergedMessage
    }
    
    
}

extension String {
    func stringByTrim() -> String {
        return self.trimmingCharacters(in: .whitespacesAndNewlines)
    }
}

struct AIParseMessagePart:HandyJSON {
    var inputSensitive:Bool = false
    var outputSsensitive:Bool = false
    var choices:[AIParseMessagePartChoice] = []
}

struct AIParseMessagePartChoice:HandyJSON {
    var finish_reason:String = ""
    var delta:AIDeltaContent?
    var deltas:String = ""
    var index:Int?
}

struct AIDeltaContent:HandyJSON {
    var content:String?
    var role:String?
}

//    var messages:[AIParseMessagePartContent] = []

//
//struct AIParseMessagePartContent:HandyJSON {
//    var senderType:String?
//    var senderName:String?
//    var text:String?
//}


